package com.ruoyi.web.controller.ring.app;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson2.JSON;
import com.google.gson.Gson;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.PlanStatusEnums;
import com.ruoyi.common.enums.YesOrNoEnums;
import com.ruoyi.common.utils.DateCalculationUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.Builder;
import com.ruoyi.ora.constant.BizConstants;
import com.ruoyi.ring.domain.RingHealthPlan;
import com.ruoyi.ring.domain.dto.RingHealthPlanClaimPointsDTO;
import com.ruoyi.ring.domain.dto.RingHealthPlanDTO;
import com.ruoyi.ring.domain.dto.RingHealthPlanQueryDTO;
import com.ruoyi.ring.domain.vo.ExerciseInfoVO;
import com.ruoyi.ring.factory.AiFactory;
import com.ruoyi.ring.service.IRingHealthPlanService;
import com.ruoyi.ring.service.IRingHrvInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 行动-健康计划 （APP）
 */
@Slf4j
@RestController
@RequestMapping("/ring/app/ring_health_plan")
public class AppHealthPlanController extends BaseController
{
    @Resource
    private IRingHealthPlanService ringHealthPlanService;
    @Resource
    private IRingHrvInfoService ringHrvInfoService;

    /**
     * 获取平均心率变异性-app
     */
    @GetMapping(value = "/query-plan-hrv-info")
    public AjaxResult queryPlanHrvInfo() {
        long userId = SecurityUtils.getUserId();
        log.info("平均心率变异性queryPlanHrvInfo: userId={}", userId);
        return AjaxResult.success(ringHrvInfoService.queryPlanHrvInfo());
    }

    /**
     * 通过步数计算每日摄入卡路里，运动消耗时长、运动消耗卡路里-app
     */
    @GetMapping(value = "/query-exercise-info/{stepCount}")
    public AjaxResult queryExerciseInfo(@PathVariable("stepCount") Integer stepCount){
        long userId = SecurityUtils.getUserId();
        log.info("通过步数计算每日摄入卡路里，运动消耗时长、运动消耗卡路里: userId={}, param={}", userId, JSON.toJSONString(stepCount));
        String aiContent = stepCount+", 请给以上步数计算出需要每日摄入卡路里，运动消耗时长、运动消耗卡路里，要全数字，按照举例返回,例如：{\"dailyCalorieIntake\":xx,\"exerciseConsumptionDuration\":xx,\"exerciseBurnsCalories\":xx}，不要其他任何内容";
        String jsonStr = AiFactory.build(BizConstants.AI_PLATFORM.getValue()).chatCompletions(aiContent);
        Gson gson = new Gson();
        Map<String, Object> resultMap = gson.fromJson(jsonStr, Map.class);
        ExerciseInfoVO infoVO = new ExerciseInfoVO();
        infoVO.setExerciseDuration(Convert.toInt(resultMap.get("exerciseConsumptionDuration")));
        infoVO.setExerciseCalorie(Convert.toInt(resultMap.get("exerciseBurnsCalories")));
        infoVO.setCalorie(Convert.toInt(resultMap.get("dailyCalorieIntake")));
        return AjaxResult.success(infoVO);
    }

    /**
     * 健康计划上报-app(单独上报 或 所有状态保存并启用新计划)
     */
    @Log(title = "健康计划", businessType = BusinessType.INSERT)
    @PostMapping("/add-health-plan")
    public AjaxResult addHealthPlan(@RequestBody RingHealthPlanDTO ringHealthPlanDTO){
        long userId = SecurityUtils.getUserId();
        log.info("健康计划上报addHealthPlan: userId={}, param={}", userId, JSON.toJSONString(ringHealthPlanDTO));
        RingHealthPlan healthPlan = ringHealthPlanService.selectOneRingHealthPlan(Builder.of(RingHealthPlan::new).
                with(RingHealthPlan::setUserId, userId).
                with(RingHealthPlan::setPlanStatus, PlanStatusEnums.IN_PROGRESS.getCode()).build());
        if(healthPlan != null && PlanStatusEnums.IN_PROGRESS.getCode().equals(ringHealthPlanDTO.getPlanStatus())){
            RingHealthPlan ringHealthPlan = new RingHealthPlan();
            ringHealthPlan.setId(healthPlan.getId());
            ringHealthPlan.setPlanStatus(PlanStatusEnums.COMPLETED.getCode());
            ringHealthPlan.setEarlyEndDate(DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.getDate()));
            ringHealthPlanService.updateRingHealthPlan(ringHealthPlan);
            ringHealthPlanDTO.setId(null);
        }
        RingHealthPlan ringHealthPlan = Convert.convert(RingHealthPlan.class,ringHealthPlanDTO);
        ringHealthPlan.setUserId(userId);
        if(PlanStatusEnums.IN_PROGRESS.getCode().equals(ringHealthPlan.getPlanStatus())){
            Date date = new Date();
            ringHealthPlan.setStartDate(date);
            Date futureDate = DateCalculationUtil.queryFutureDate(date,ringHealthPlan.getPlanCycle());
            ringHealthPlan.setEndDate(futureDate);
        }
        int result = ringHealthPlanService.insertRingHealthPlan(ringHealthPlan);
        if(result > 0){
            return AjaxResult.success(ringHealthPlan);
        }else {
            return toAjax(result);
        }
    }
    /**
     * 健康计划编辑-app
     */
    @Log(title = "健康计划", businessType = BusinessType.UPDATE)
    @PostMapping("/upd-health-plan")
    public AjaxResult updHealthPlan(@RequestBody RingHealthPlanDTO ringHealthPlanDTO){
        long userId = SecurityUtils.getUserId();
        log.info("健康计划updHealthPlan: userId={}, param={}", userId, JSON.toJSONString(ringHealthPlanDTO));
        RingHealthPlan healthPlan = ringHealthPlanService.selectOneRingHealthPlan(Builder.of(RingHealthPlan::new).
                with(RingHealthPlan::setUserId, userId).
                with(RingHealthPlan::setPlanStatus, PlanStatusEnums.IN_PROGRESS.getCode()).build());
        if(healthPlan != null && PlanStatusEnums.IN_PROGRESS.getCode().equals(ringHealthPlanDTO.getPlanStatus())){
            healthPlan.setPlanStatus(PlanStatusEnums.COMPLETED.getCode());
            healthPlan.setEarlyEndDate(DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.getDate()));
            ringHealthPlanService.updateRingHealthPlan(healthPlan);
        }
        RingHealthPlan ringHealthPlan = Convert.convert(RingHealthPlan.class,ringHealthPlanDTO);
        ringHealthPlan.setUserId(userId);
        if(PlanStatusEnums.IN_PROGRESS.getCode().equals(ringHealthPlan.getPlanStatus())){
            Date date = new Date();
            ringHealthPlan.setStartDate(date);
            Date futureDate = DateCalculationUtil.queryFutureDate(date,ringHealthPlan.getPlanCycle());
            ringHealthPlan.setEndDate(futureDate);
        }
        return toAjax(ringHealthPlanService.updateRingHealthPlan(ringHealthPlan));
    }
    /**
     * 获取健康计划详细信息-app
     */
    @GetMapping(value = "/query-id/{queryId}")
    public AjaxResult queryInfo(@PathVariable("queryId") Long queryId)
    {
        return AjaxResult.success(ringHealthPlanService.selectRingHealthPlanById(queryId));
    }
    /**
     * 查询健康计划列表-app
     */
    @GetMapping("/query-list")
    public AjaxResult queryList(RingHealthPlanQueryDTO queryDTO){
        long userId = SecurityUtils.getUserId();
        log.info("健康计划列表queryList: userId={}, param={}", userId, JSON.toJSONString(queryDTO));
        List<RingHealthPlan> list = ringHealthPlanService.selectRingHealthPlanList(Builder.of(RingHealthPlan::new).
                with(RingHealthPlan::setPlanStatus, queryDTO.getPlanStatus()).
                with(RingHealthPlan::setUserId, SecurityUtils.getUserId()).build());
        return AjaxResult.success(list);
    }

    /**
     * 领取积分-app
     */
    @Log(title = "领取积分", businessType = BusinessType.UPDATE)
    @PostMapping("/claim-points")
    public AjaxResult claimPoints(@RequestBody RingHealthPlanClaimPointsDTO claimPointsDTO){
        long userId = SecurityUtils.getUserId();
        log.info("领取积分claimPoints: userId={}, param={}", userId, JSON.toJSONString(claimPointsDTO));
        RingHealthPlan ringHealthPlan = Convert.convert(RingHealthPlan.class,claimPointsDTO);
        ringHealthPlan.setIsClaim(YesOrNoEnums.YES.getCode());
        return toAjax(ringHealthPlanService.updateRingHealthPlan(ringHealthPlan));
    }

    /**
     * 启用计划-app
     */
    @Log(title = "启用计划", businessType = BusinessType.UPDATE)
    @PostMapping("/enable-health-plan")
    public AjaxResult enableHealthPlan(@RequestBody RingHealthPlanDTO ringHealthPlanDTO){
        long userId = SecurityUtils.getUserId();
        log.info("启用计划enableHealthPlan: userId={}, param={}", userId, JSON.toJSONString(ringHealthPlanDTO));
        RingHealthPlan healthPlan = ringHealthPlanService.selectOneRingHealthPlan(Builder.of(RingHealthPlan::new).
                with(RingHealthPlan::setUserId, userId).
                with(RingHealthPlan::setPlanStatus, PlanStatusEnums.IN_PROGRESS.getCode()).build());
        if(healthPlan != null){
            healthPlan.setPlanStatus(PlanStatusEnums.COMPLETED.getCode());
            healthPlan.setEarlyEndDate(DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.getDate()));
            ringHealthPlanService.updateRingHealthPlan(healthPlan);
        }
        RingHealthPlan ringHealthPlan = Convert.convert(RingHealthPlan.class,ringHealthPlanDTO);
        ringHealthPlan.setUserId(userId);
        ringHealthPlan.setPlanStatus(PlanStatusEnums.IN_PROGRESS.getCode());
        Date date = new Date();
        ringHealthPlan.setStartDate(date);
        Date futureDate = DateCalculationUtil.queryFutureDate(date,ringHealthPlan.getPlanCycle());
        ringHealthPlan.setEndDate(futureDate);
        return toAjax(ringHealthPlanService.updateRingHealthPlan(ringHealthPlan));
    }


}
